// ComputerPlayer.cpp : implementation file
//

#include "stdafx.h"
#include "Five.h"
#include "FiveDoc.h"
#include "FiveView.h"
#include "mainfrm.h"
#include "chessai.h"
#include "simpleai.h"
#include "ComputerPlayer.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CComputerPlayer

IMPLEMENT_DYNCREATE(CComputerPlayer, CWinThread)

CComputerPlayer::CComputerPlayer()
{
	m_pData = 0;
	m_pAI =0 ;
}

CComputerPlayer::~CComputerPlayer()
{

}

BOOL CComputerPlayer::InitInstance()
{
	// TODO:  perform and per-thread initialization here
	m_pData = &GetChessBoard().m_data;
	m_pAI = new CSimpleAI(*m_pData);
	return TRUE;
}

int CComputerPlayer::ExitInstance()
{
	// TODO:  perform any per-thread cleanup here
	if(m_pAI)
	{
		delete m_pAI;
		m_pAI = 0;
	}
	return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(CComputerPlayer, CWinThread)
	//{{AFX_MSG_MAP(CComputerPlayer)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
	ON_THREAD_MESSAGE(MSG_COMPUTER_TURN,PutChess)
	ON_THREAD_MESSAGE(MSG_GAME_OVER,GameOver)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CComputerPlayer message handlers

BOOL CComputerPlayer::OnIdle(LONG lCount) 
{
	// TODO: Add your specialized code here and/or call the base class
	m_pAI->Think();
	return CWinThread::OnIdle(lCount);
}

void CComputerPlayer::PutChess(WPARAM wp, LPARAM lp)
{
	int x, y ;
	m_pAI->NotifyChange();

	if(!m_pAI->GetBestStep(GetChessBoard().GetCurrentPlayer(),x,y))
	{
		while(true)
		{
			x = rand()%CHESS_GRID_NUM;
			y = rand()%CHESS_GRID_NUM;
			if(m_pData->Get(x,y)==NONE_CHESS)
			{
				break;
			}
		}
	}

	GetView()->SendMessage(MSG_PUT_CHESS,x,y);

	m_pAI->NotifyChange();
}

void CComputerPlayer::GameOver(WPARAM wp, LPARAM lp)
{
	::AfxEndThread(0,true);
}

CFiveDoc* CComputerPlayer::GetDocument()
{
	extern CFiveApp theApp;
	POSITION curTemplatePos = theApp.GetFirstDocTemplatePosition();
    CDocTemplate *doctempl=theApp.GetNextDocTemplate(curTemplatePos);
	POSITION docPos = doctempl->GetFirstDocPosition();
	CDocument * doc = doctempl->GetNextDoc(docPos);
	
	return (CFiveDoc*)doc;
}

CChessBoard & CComputerPlayer::GetChessBoard()
{
	return GetDocument()->m_cb;
}

CFiveView * CComputerPlayer::GetView()
{
	extern CFiveApp theApp;
	CMainFrame *wnd =(CMainFrame *)theApp.m_pMainWnd;
	CFiveView * view =(CFiveView *)wnd->GetActiveView();
	return view;
}
